package com.bkhech.spring.security.example.accesstoken.oauth2.impl;

import cn.hutool.core.util.RandomUtil;
import com.bkhech.spring.security.example.accesstoken.oauth2.OAuth2TokenApi;
import com.bkhech.spring.security.example.accesstoken.oauth2.dto.OAuth2AccessTokenCheckRespDto;
import com.bkhech.spring.security.example.accesstoken.oauth2.dto.OAuth2AccessTokenCreateReqDto;
import com.bkhech.spring.security.example.accesstoken.oauth2.dto.OAuth2AccessTokenRespDto;
import com.bkhech.spring.security.example.domain.dao.UserInfo;
import com.bkhech.spring.security.example.service.UserService;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * OAuth2.0 Token API 实现类
 *
 * @author guowm
 * @date 2023/2/1
 */
@Service
public class OAuth2TokenApiImpl implements OAuth2TokenApi {

    @Override
    public OAuth2AccessTokenRespDto createAccessToken(OAuth2AccessTokenCreateReqDto reqDto) {
        return accessTokenMap.get(reqDto.getUserId());
    }

    @SuppressWarnings("DataFlowIssue")
    @Override
    public OAuth2AccessTokenRespDto removeAccessToken(String accessToken) {
        for (Map.Entry<Long, OAuth2AccessTokenRespDto> entry : accessTokenMap.entrySet()) {
            if (entry.getValue().getAccessToken().equals(accessToken)) {
                return accessTokenMap.remove(entry.getKey());
            }
        }
        return null;
    }

    @SuppressWarnings("DataFlowIssue")
    @Override
    public OAuth2AccessTokenRespDto refreshAccessToken(String refreshToken, String clientId) {
        for (Map.Entry<Long, OAuth2AccessTokenRespDto> entry : accessTokenMap.entrySet()) {
            if (entry.getValue().getRefreshToken().equals(refreshToken)) {
                final OAuth2AccessTokenRespDto respDto = accessTokenMap.remove(entry.getKey());

                final OAuth2AccessTokenRespDto refreshRespDto = new OAuth2AccessTokenRespDto();
                refreshRespDto.setUserId(respDto.getUserId());
                refreshRespDto.setExpiresTime(LocalDateTime.now().plusHours(1));
                refreshRespDto.setAccessToken(RandomUtil.randomString(12));
                refreshRespDto.setRefreshToken(RandomUtil.randomString(12));

                accessTokenMap.put(respDto.getUserId(), refreshRespDto);

                return refreshRespDto;
            }
        }
        return null;
    }

    @Override
    public OAuth2AccessTokenCheckRespDto checkAccessToken(String accessToken) {
        for (Map.Entry<Long, OAuth2AccessTokenRespDto> entry : accessTokenMap.entrySet()) {
            if (entry.getValue().getAccessToken().equals(accessToken)) {
                final Long userId = entry.getKey();
                for (Map.Entry<String, UserInfo> userInfoEntry : UserService.users.entrySet()) {
                    if (userInfoEntry.getValue().getId().equals(userId)) {
                        final OAuth2AccessTokenCheckRespDto checkRespDto = new OAuth2AccessTokenCheckRespDto();
                        checkRespDto.setUserId(userId);
                        checkRespDto.setTenantId(1L);
                        // 设置权限
                        checkRespDto.setScopes(List.of(userInfoEntry.getValue().getRole()));
                        return checkRespDto;
                    }
                }
            }
        }
        return null;
    }
}
